package org.japo.java.entities;

import java.io.Serializable;
import java.util.StringTokenizer;

/**
 *
 * @author José A. Pacheco Ondoño - joanpaon@gmail.com
 */
public class CodigoCuentaBancaria implements Serializable {
    // Separador de campos
    public static final String SEPARADOR = "-";

    // Campos del código de cuenta bancaria
    private String entidad;
    private String oficina;
    private String control;
    private String cuenta;

    public CodigoCuentaBancaria() {
        entidad = "0000";
        oficina = "0000";
        control = "00";
        cuenta = "0000000000";
    }

    public CodigoCuentaBancaria(String entidad, String oficina, 
            String control, String cuenta) {
        entidad = "0000" + entidad.trim();
        this.entidad = entidad.substring(entidad.length() - 4);
        oficina = "0000" + oficina.trim();
        this.oficina = oficina.substring(oficina.length() - 4);
        control = "00" + control.trim();
        this.control = control.substring(control.length() - 2);
        cuenta = "0000000000" + cuenta.trim();
        this.cuenta = cuenta.substring(cuenta.length() - 10);
    }

    public String getEntidad() {
        return entidad;
    }

    public void setEntidad(String entidad) {
        entidad = "0000" + entidad.trim();
        this.entidad = entidad.substring(entidad.length() - 4);
    }

    public String getOficina() {
        return oficina;
    }

    public void setOficina(String oficina) {
        oficina = "0000" + oficina.trim();
        this.oficina = oficina.substring(oficina.length() - 4);
    }

    public String getControl() {
        return control;
    }

    public void setControl(String control) {
        control = "00" + control.trim();
        this.control = control.substring(control.length() - 2);
    }

    public String getCuenta() {
        return cuenta;
    }

    public void setCuenta(String cuenta) {
        cuenta = "0000000000" + cuenta.trim();
        this.cuenta = cuenta.substring(cuenta.length() - 10);
    }

    @Override
    public String toString() {
        return entidad + SEPARADOR + oficina + SEPARADOR + control + SEPARADOR + cuenta;
    }

    public static CodigoCuentaBancaria parseCodigoCuentaBancaria(String textoCCB) {
        // Referencia al objeto a devolver
        CodigoCuentaBancaria ccb = new CodigoCuentaBancaria();

        // Crea un objeto StringTokenizer a partir del dato
        StringTokenizer st = new StringTokenizer(textoCCB, SEPARADOR);

        // Analiza el objeto creado
        if (st.countTokens() == 4) {
            // Entidad
            ccb.setEntidad(st.nextToken());

            // Oficina
            ccb.setOficina(st.nextToken());

            // Control
            ccb.setControl(st.nextToken());

            // Cuenta
            ccb.setCuenta(st.nextToken());            
        }
        
        // Devuelve el objeto generado
        return ccb;
    }

    public static String generarControl(CodigoCuentaBancaria ccb) {
        // Control - DMS
        int numEntidad = Integer.parseInt(ccb.entidad);
        int numOficina = Integer.parseInt(ccb.oficina);
        char digito1 = (char) ('0' + sumarDigitosEntero(numEntidad + numOficina));

        // Control - dms
        int numCuenta = Integer.parseInt(ccb.cuenta);
        char digito2 = (char) ('0' + sumarDigitosEntero(numCuenta));

        return String.format("%c%c", digito1, digito2);
    }

    public static int sumarDigitosEntero(int numero) {
        // Acumulador
        int suma = 0;

        // Proceso de análisis
        while (numero > 0) {
            // Obtiene el dms y lo acumula
            suma += numero % 10;

            // Ajusta la acumulacion
            if (suma > 9) {
                suma = suma - 10 + 1;
            }

            // Actualiza el numero
            numero = numero / 10;
        }

        // Devuelve el número calculado
        return suma;
    }

    public static boolean validarCodigoCuentaBancaria(CodigoCuentaBancaria ccb) {
        // Semáforo de validez
        boolean validezOK = false;

        // Código a comprobar
        String codigoExpresado = ccb.getControl();

        // Código calculado
        String codigoCalculado = generarControl(ccb);

        // Análisis
        if (codigoExpresado.equals(codigoCalculado)) {
            validezOK = true;
        }

        // Devolver el resultado del análisis
        return validezOK;
    }
}
